package com.rex.saas.controller.ct;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.rex.saas.bean.BaseResponse;
import com.rex.saas.bean.DeviceBasicData;
import com.rex.saas.bean.DeviceTimeSeries;
import com.rex.saas.bean.ResultCode;
import com.rex.saas.bean.request.*;
import com.rex.saas.bean.response.*;
import com.rex.saas.constants.Constants;
import com.rex.saas.controller.BaseController;
import com.rex.saas.db.entity.SaasDeviceEvent;
import com.rex.saas.db.entity.SaasDeviceInfo;
import com.rex.saas.db.entity.SaasDeviceLabel;
import com.rex.saas.db.entity.SaasSpaceLabel;
import com.rex.saas.enums.CtDeviceTypeEnum;
import com.rex.saas.service.CategoryService;
import com.rex.saas.service.DeviceService;
import com.rex.saas.service.LabelService;
import com.rex.saas.service.RexolarApiClient;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName DeviceController
 * @Description:
 * @Author: zhusiyu
 * @CreateDate: 2024/12/18 10:55	//创建时间
 */
@RestController
@Slf4j
@RequestMapping("/ct")
public class CtDeviceController extends BaseController {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private LabelService labelService;

    @Autowired
    private RexolarApiClient rexolarApiClient;

    private static long ONE_DAY_MILLISECONDS = 24 * 60 * 60 * 1000;

    @PostMapping("/label")
    @ResponseBody
    public BaseResponse label(HttpServletRequest request, @RequestBody DeviceLabelRequest deviceLabelRequest){
        log.info("label ===> deviceLabelRequest:{}", deviceLabelRequest);
        if(StringUtils.isBlank(deviceLabelRequest.getDeviceName())){
            log.error("label deviceName is null, deviceLabelRequest:{}", deviceLabelRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }

        if(deviceLabelRequest.getSpaceLabelId()==null && deviceLabelRequest.getDeviceLabelId()==null){
            log.error("label spaceLabelId and deviceLabelId is null, deviceLabelRequest:{}", deviceLabelRequest);
            return BaseResponse.error("空间标签id和设备标签id都为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("label tenantId is null, deviceLabelRequest:{}", deviceLabelRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        String customerId = JwtUtils.getCustomerId(token);
        if(StringUtils.isBlank(customerId)){
            log.error("label customerId is null, deviceLabelRequest:{}", deviceLabelRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.CUSTOMER_USER)){
            log.error("label role is not CUSTOMER_USER, deviceLabelRequest:{}", deviceLabelRequest);
            return BaseResponse.error("权限不足", ResultCode.PARAM_ERROR);
        }
        BaseResponse baseResponse = validateDeviceName(deviceLabelRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("label validateDeviceName error, deviceName:{}", deviceLabelRequest.getDeviceName());
            return baseResponse;
        }

        if(deviceLabelRequest.getSpaceLabelId()!=null){
            SaasSpaceLabel spaceLabel = labelService.getSpaceLabelById(deviceLabelRequest.getSpaceLabelId());
            if (spaceLabel==null){
                log.error("label spaceLabel is not exist, deviceLabelRequest:{}", deviceLabelRequest);
                return BaseResponse.error("空间标签不存在", ResultCode.PARAM_ERROR);
            }
            if (spaceLabel.getCustomerId() !=null && !spaceLabel.getCustomerId().equals(JwtUtils.getCustomerId(token))){
                log.error("spaceLabel no permission, deviceLabelRequest:{}", deviceLabelRequest);
                return BaseResponse.error("用户没有空间标签权限", ResultCode.PARAM_ERROR);
            }
        }

        String deviceLabel = null;
        if(deviceLabelRequest.getDeviceLabelId()!=null){
            SaasDeviceLabel saasDeviceLabel = labelService.getDeviceLabelById(deviceLabelRequest.getDeviceLabelId());
            if (saasDeviceLabel==null){
                log.error("label deviceLabel is not exist, deviceLabelRequest:{}", deviceLabelRequest);
                return BaseResponse.error("设备标签不存在", ResultCode.PARAM_ERROR);
            }
            if (saasDeviceLabel.getCustomerId() !=null && !saasDeviceLabel.getCustomerId().equals(JwtUtils.getCustomerId(token))){
                log.error("deviceLabel no permission, deviceLabelRequest:{}", deviceLabelRequest);
                return BaseResponse.error("用户没有设备标签权限", ResultCode.PARAM_ERROR);
            }
            if(StringUtils.isBlank(saasDeviceLabel.getCustomerId())
                    && !saasDeviceLabel.getSpaceLabelId().equals(deviceLabelRequest.getSpaceLabelId())){
                log.error("label spaceLabelId is not equal, deviceLabelRequest:{}", deviceLabelRequest);
                return BaseResponse.error("设备标签与空间标签不匹配", ResultCode.PARAM_ERROR);
            }
            deviceLabel = saasDeviceLabel.getLabelName();
        }


        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("label tenantToken is null, deviceLabelRequest:{}",deviceLabelRequest);
            return BaseResponse.error("租户token异常", ResultCode.SYSTEM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceLabelRequest.getDeviceName(), tenantToken);
        if (deviceBasicData==null){
            log.error("label getDeviceByDeviceName error, deviceName:{}", deviceLabelRequest.getDeviceName());
            return BaseResponse.error("设备不存在：" + deviceLabelRequest.getDeviceName() , ResultCode.PARAM_ERROR);
        }

        if(!deviceService.setLabel(deviceLabelRequest, deviceLabel)){
            log.error("label setLabel error, deviceBindRequest:{}", deviceLabelRequest);
            return BaseResponse.error("客户设置设备标签失败", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(true);
    }

    @PostMapping("/unbind")
    @ResponseBody
    public BaseResponse unbind(HttpServletRequest request, @RequestBody DeviceUnBindRequest deviceUnBindRequest){
        log.info("unbind ===> deviceUnBindRequest:{}", deviceUnBindRequest);
        if(StringUtils.isBlank(deviceUnBindRequest.getDeviceName())){
            log.error("unbind deviceName is null, deviceUnBindRequest:{}", deviceUnBindRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        BaseResponse baseResponse = validateDeviceName(deviceUnBindRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("unbind validateDeviceName error, deviceName:{}", deviceUnBindRequest.getDeviceName());
            return baseResponse;
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("unbind tenantToken is null, deviceUnBindRequest:{}",deviceUnBindRequest);
            return BaseResponse.error("租户token异常", ResultCode.SYSTEM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceUnBindRequest.getDeviceName(), tenantToken);
        if (deviceBasicData==null){
            log.error("unbind getDeviceByDeviceName error, deviceName:{}", deviceUnBindRequest.getDeviceName());
            return BaseResponse.error("设备不存在：" + deviceUnBindRequest.getDeviceName() , ResultCode.PARAM_ERROR);
        }

        SaasDeviceInfo deviceInfo = deviceService.getDeviceByName(deviceUnBindRequest.getDeviceName(), tenantId);
        if(!deviceService.networkLeave(deviceInfo, tenantToken)){
            log.error("unbind networkLeave error, deviceUnBindRequest:{}", deviceUnBindRequest);
            return BaseResponse.error("设备离网失败", ResultCode.SYSTEM_ERROR);
        }
        if(!deviceService.deleteCustomerDevice(deviceInfo, tenantToken)){
            log.error("unbind deleteCustomerDevice error, deviceUnBindRequest:{}", deviceUnBindRequest);
            return BaseResponse.error("解绑失败", ResultCode.SYSTEM_ERROR);
        }
        return BaseResponse.ok();
    }
    @PostMapping("/bindSpace")
    @ResponseBody
    public BaseResponse bindSpace(HttpServletRequest request, @RequestBody DeviceBindSpaceRequest deviceBindSpaceRequest){
        log.info("bindSpace ===> deviceBindSpaceRequest:{}", deviceBindSpaceRequest);
        if(StringUtils.isBlank(deviceBindSpaceRequest.getDeviceName())){
            log.error("bindSpace deviceName is null, deviceBindSpaceRequest:{}", deviceBindSpaceRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if (deviceBindSpaceRequest.getSpaceId()==null){
            log.error("bindSpace spaceId is null, deviceBindSpaceRequest:{}", deviceBindSpaceRequest);
            return BaseResponse.error("spaceId参数为空", ResultCode.PARAM_ERROR);
        }
        if (deviceBindSpaceRequest.getType()==null){
            log.error("bindSpace type is null, deviceBindSpaceRequest:{}", deviceBindSpaceRequest);
            return BaseResponse.error("type参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateDeviceName(deviceBindSpaceRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("bindSpace validateDeviceName error, deviceName:{}", deviceBindSpaceRequest.getDeviceName());
            return baseResponse;
        }
        baseResponse = validateSpace(deviceBindSpaceRequest.getSpaceId(), token);
        if(!baseResponse.isSuccess()){
            log.error("bindSpace validateSpace error, spaceId:{}", deviceBindSpaceRequest.getSpaceId());
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.bindSpace(deviceBindSpaceRequest.getDeviceName(), deviceBindSpaceRequest.getSpaceId(), deviceBindSpaceRequest.getType(), token));
    }
    @PostMapping("/bind")
    @ResponseBody
    public BaseResponse bind(HttpServletRequest request, @RequestBody DeviceBindRequest deviceBindRequest){
        log.info("bind ===> deviceBindRequest:{}", deviceBindRequest);
        if(StringUtils.isBlank(deviceBindRequest.getDeviceName())){
            log.error("bind deviceName is null, deviceBindRequest:{}", deviceBindRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("bind tenantId is null, deviceBindRequest:{}", deviceBindRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        String customerId = JwtUtils.getCustomerId(token);
        if(StringUtils.isBlank(customerId)){
            log.error("bind customerId is null, deviceBindRequest:{}", deviceBindRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        List<String> roles = JwtUtils.getRole(token);
        if(!roles.contains(Constants.CUSTOMER_USER)){
            log.error("bind role is not CUSTOMER_USER, deviceBindRequest:{}", deviceBindRequest);
            return BaseResponse.error("权限不足", ResultCode.PARAM_ERROR);
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("bind tenantToken is null, deviceBindRequest:{}",deviceBindRequest);
            return BaseResponse.error("租户token异常", ResultCode.SYSTEM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceBindRequest.getDeviceName(), tenantToken);
        if (deviceBasicData==null){
            log.error("bind getDeviceByDeviceName error, deviceName:{}", deviceBindRequest.getDeviceName());
            return BaseResponse.error("设备不存在：" + deviceBindRequest.getDeviceName() , ResultCode.PARAM_ERROR);
        }

        SaasDeviceInfo deviceInfo = deviceService.getDeviceByName(deviceBindRequest.getDeviceName(), tenantId);
        if(deviceInfo==null){
            log.error("bind getDeviceByName error, deviceName:{}", deviceBindRequest.getDeviceName());
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        if(StringUtils.isNotBlank(deviceInfo.getCustomerId()) && !JwtUtils.getCustomerId(token).equals(deviceInfo.getCustomerId())){
            log.error("bind customerId not match error, deviceName:{}", deviceBindRequest.getDeviceName());
            return BaseResponse.error("设备已经被其他用户绑定", ResultCode.PARAM_ERROR);
        }

        if(!deviceService.bindCustomerDevice(deviceInfo, customerId, tenantToken)){
            log.error("bind addDevice error, deviceBindRequest:{}", deviceBindRequest);
            return BaseResponse.error("客户绑定设备失败", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(true);
    }

    @GetMapping("/detail")
    public BaseResponse detail(HttpServletRequest request, @RequestParam String deviceName){
        log.info("ctDetail ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("ctDetail deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("ctDetail validateDeviceName error, deviceName:{}", deviceName);
            return baseResponse;
        }
        SaasDeviceInfo saasDeviceInfo = deviceService.getDeviceByName(deviceName, tenantId);
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("ctDetail tenantToken is null, deviceName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
        if(deviceBasicData==null){
            log.error("ctDetail getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        Long id = (Long) baseResponse.getData();
        CtDeviceDetailResponse devicesResponse = deviceService.ctDetail(deviceBasicData, tenantToken);
        if(StringUtils.isNotBlank(saasDeviceInfo.getDeviceAlias())){
            devicesResponse.setDeviceAlias(saasDeviceInfo.getDeviceAlias());
        }
        Map<String, String> deviceProfilesImage = rexolarApiClient.getDeviceProfilesImage(tenantToken);
        devicesResponse.setCategoryImage(deviceProfilesImage.get(deviceBasicData.getProfileId()));
        devicesResponse.setId(id);
        devicesResponse.setCustomerId(saasDeviceInfo.getCustomerId());
        return BaseResponse.ok(devicesResponse);
    }

    @GetMapping("/bindInfo")
    public BaseResponse bindInfo(HttpServletRequest request, @RequestParam String deviceName){
        log.info("bindInfo ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("bindInfo deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        SaasDeviceInfo saasDeviceInfo = deviceService.getDeviceByName(deviceName, tenantId);
        if(saasDeviceInfo==null){
            log.error("bindInfo deviceName is not exist, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("bindInfo tenantToken is null, deviceName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBaseInfoResponse devicesResponse = new DeviceBaseInfoResponse();
        BeanUtils.copyProperties(saasDeviceInfo, devicesResponse);
        return BaseResponse.ok(devicesResponse);
    }
    @GetMapping("/version")
    public BaseResponse version(HttpServletRequest request, @RequestParam String deviceName){
        log.info("version ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("version deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("version validateDeviceName error, deviceName:{}", deviceName);
            return baseResponse;
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("version tenantToken is null, deviceName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
        if(deviceBasicData==null){
            log.error("version getDeviceByDeviceName error, deviceName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        Map<String,Object> attributes = rexolarApiClient.getDeviceAttributes(deviceBasicData.getCoreId(), tenantToken, new String[]{Constants.SWBuildID});
        if (!CollectionUtils.isEmpty(attributes)){
            return BaseResponse.ok(attributes.get(Constants.SWBuildID)==null?"":attributes.get(Constants.SWBuildID).toString());
        }else{
            return BaseResponse.ok("");
        }
    }

    @GetMapping("/direction")
    public BaseResponse ctDirection(HttpServletRequest request, @RequestParam String deviceName){
        log.info("ctDirection ===> deviceName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("ctDirection deviceName is null, deviceName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("ctDirection validateDeviceName error, gwName:{}", deviceName);
            return baseResponse;
        }
        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("ctDirection tenantToken is null, gwName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
        if(deviceBasicData==null){
            log.error("ctDirection getDeviceByDeviceName error, gwName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        Map<String, List<DeviceTimeSeries>> deviceTimeSeriesMap = rexolarApiClient.getDeviceTimeSeriesLatest(deviceBasicData.getCoreId(), tenantToken,
                new String[]{Constants.CT_DIRECTION}, false);
        if (!CollectionUtils.isEmpty(deviceTimeSeriesMap)){
            if(deviceTimeSeriesMap.get(Constants.CT_DIRECTION)!=null){
                List<DeviceTimeSeries> values = deviceTimeSeriesMap.get(Constants.CT_DIRECTION);
                JSONObject jsonObject = JSONObject.parseObject(values.get(0).toJSONString());
                int direction = Integer.parseInt(jsonObject.getString("value"));
                String binaryStr = Integer.toBinaryString(direction);
                if(binaryStr.length()==1){
                    binaryStr = "000"+binaryStr;
                }else if(binaryStr.length()==2){
                    binaryStr = "00"+binaryStr;
                }else if(binaryStr.length()==3){
                    binaryStr = "0"+binaryStr;
                }
                CtDirectionResponse ctDirectionResponse = new CtDirectionResponse();
                ctDirectionResponse.setDeviceName(deviceName);
                ctDirectionResponse.setL3(binaryStr.substring(0,1));
                ctDirectionResponse.setL2(binaryStr.substring(1,2));
                ctDirectionResponse.setL1(binaryStr.substring(2,3));
                return BaseResponse.ok(ctDirectionResponse);
            }
        }
        return BaseResponse.ok("");
    }
    @GetMapping("/labels")
    public BaseResponse labels(HttpServletRequest request, @RequestParam String deviceName) {
        log.info("labels ===> gwName:{}", deviceName);
        if (StringUtils.isBlank(deviceName)) {
            log.error("labels gwName is null, gwName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if (!baseResponse.isSuccess()) {
            log.error("labels validateDeviceName error, gwName:{}", deviceName);
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.getDeviceLabels(deviceName));
    }

    @GetMapping("/power")
    public BaseResponse power(HttpServletRequest request, @RequestParam String deviceName){
        log.info("power ===> gwName:{}", deviceName);
        if(StringUtils.isBlank(deviceName)){
            log.error("power gwName is null, gwName:{}", deviceName);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("power validateDeviceName error, gwName:{}", deviceName);
            return baseResponse;
        }

        String tenantToken = rexolarApiClient.getTenantToken(tenantId);
        if(StringUtils.isBlank(tenantToken)){
            log.error("power tenantToken is null, gwName:{}", deviceName);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceName, tenantToken);
        if(deviceBasicData==null){
            log.error("power getDeviceByDeviceName error, gwName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        Long deviceId = (Long) baseResponse.getData();
        CtDevicePowerResponse devicesResponse = deviceService.ctPower(deviceBasicData, tenantToken);
        devicesResponse.setId(deviceId);
        return BaseResponse.ok(devicesResponse);
    }

    @PostMapping("/set")
    public BaseResponse set(HttpServletRequest request, @RequestBody CtSetRequest ctSetRequest){
        log.info("ctSet ===> ctSetRequest:{}", ctSetRequest);
        if(StringUtils.isBlank(ctSetRequest.getDeviceName())
                || StringUtils.isBlank(ctSetRequest.getL1())
                || StringUtils.isBlank(ctSetRequest.getL2())
                || StringUtils.isBlank(ctSetRequest.getL3())
        ){
            log.error("ctSet ctSetRequest is null, ctSetRequest:{}", ctSetRequest);
            return BaseResponse.error("参数为空", ResultCode.PARAM_ERROR);
        }
        if(!"0".equals(ctSetRequest.getL1())&& !"1".equals(ctSetRequest.getL1())){
            log.error("ctSet l1 is error, l1:{}", ctSetRequest.getL1());
            return BaseResponse.error("l1参数错误", ResultCode.PARAM_ERROR);
        }
        if(!"0".equals(ctSetRequest.getL2())&& !"1".equals(ctSetRequest.getL2())){
            log.error("ctSet l2 is error, l2:{}", ctSetRequest.getL2());
            return BaseResponse.error("l2参数错误", ResultCode.PARAM_ERROR);
        }
        if(!"0".equals(ctSetRequest.getL3())&& !"1".equals(ctSetRequest.getL3())){
            log.error("ctSet l3 is error, l3:{}", ctSetRequest.getL3());
            return BaseResponse.error("l3参数错误", ResultCode.PARAM_ERROR);
        }

        String token = request.getHeader("token");

        BaseResponse baseResponse = validateDeviceName(ctSetRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("ctSet validateDeviceName error, gwName:{}", ctSetRequest.getDeviceName());
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.ctSet(ctSetRequest, token));
    }


    @PostMapping("events")
    public BaseResponse events(HttpServletRequest request, @RequestBody EventsRequest eventsRequest){
        log.info("events ===> eventsRequest:{}", eventsRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("events tenantId is null, eventsRequest:{}", eventsRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        if(eventsRequest.getDeviceName()==null){
            log.error("events gwName is null, eventsRequest:{}", eventsRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        BaseResponse baseResponse = validateDeviceName(eventsRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("events validateDeviceName error, gwName:{}", eventsRequest.getDeviceName());
            return baseResponse;
        }

        if(eventsRequest.getEndTime()==null){
            eventsRequest.setEndTime(System.currentTimeMillis());
        }
        if(eventsRequest.getStartTime()==null){
            eventsRequest.setStartTime(System.currentTimeMillis() - ONE_DAY_MILLISECONDS);
        }
        if(eventsRequest.getEndTime()-eventsRequest.getStartTime() > ONE_DAY_MILLISECONDS){
            log.error("events time range error, eventsRequest:{}", eventsRequest);
            return BaseResponse.error("时间范围不能超过24小时", ResultCode.PARAM_ERROR);
        }
        List<SaasDeviceEvent> list = deviceService.events(eventsRequest, token);
        return BaseResponse.ok(list);
    }

    @PostMapping("batchAdd")
    public BaseResponse batchAdd(HttpServletRequest request, @RequestBody List<BatchAddCtRequest> batchAddCtRequest){
        log.info("batchAddCt ===> batchAddCtRequest:{}", batchAddCtRequest);
        if(CollectionUtils.isEmpty(batchAddCtRequest)){
            log.error("batchAddCt batchAddCtRequest is null, batchAddCtRequest:{}", batchAddCtRequest);
            return BaseResponse.error("batchAddCtRequest参数为空", ResultCode.PARAM_ERROR);
        }
        String token = request.getHeader("token");
        List<String> roles = JwtUtils.getRole(token);
        if (!roles.contains(Constants.TENANT_ADMIN)){
            log.error("batchAddCt , user has not permission , addOtaInfoRequest:{}", batchAddCtRequest);
            return BaseResponse.error("一般用户没有添加设备权限", ResultCode.PARAM_ERROR);
        }
        Map<String, List<BatchAddCtRequest>> categroyMap = new HashMap<>();
        Map<String, String> categroyNameMap = new HashMap<>();
        for (BatchAddCtRequest addCtRequest : batchAddCtRequest){
            CategroyResponse categroyResponse = categoryService.getDetailsByName(token, addCtRequest.getCategoryName());
            if(categroyResponse==null){
                log.error("batchAddCt categoryService getDetailsByName error, categoryName:{}", addCtRequest.getCategoryName());
                return BaseResponse.error("设备配置不存在", ResultCode.PARAM_ERROR);
            }
            categroyNameMap.put(categroyResponse.getCategoryId(), categroyResponse.getCategoryName());
            if(categroyMap.get(categroyResponse.getCategoryId())==null){
                List<BatchAddCtRequest> list = new ArrayList<>();
                list.add(addCtRequest);
                categroyMap.put(categroyResponse.getCategoryId(), list);
            }else {
                categroyMap.get(categroyResponse.getCategoryId()).add(addCtRequest);
            }
        }
        for (String key : categroyMap.keySet()){
            deviceService.batchAdd(batchAddCtRequest, key, categroyNameMap.get(key), token);
        }
        return BaseResponse.ok();
    }


    @GetMapping("/types")
    public BaseResponse types(HttpServletRequest request){
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        return BaseResponse.ok(CtDeviceTypeEnum.getList());
    }


    @PostMapping("/upload/edgeLog")
    public BaseResponse uploadEdgeLog(HttpServletRequest request, @RequestBody EdgeLogRequest edgeLogRequest){
        log.info("uploadLog ===> edgeLogRequest:{}", edgeLogRequest);
        String token = request.getHeader("token");
        if(StringUtils.isBlank(edgeLogRequest.getDeviceName())){
            log.error("uploadLog gwName is null, deviceListRequest:{}", edgeLogRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(edgeLogRequest.getLogUrl())){
            log.error("uploadLog logUrl is null, deviceListRequest:{}", edgeLogRequest);
            return BaseResponse.error("logUrl参数为空", ResultCode.PARAM_ERROR);
        }
        BaseResponse baseResponse = validateDeviceName(edgeLogRequest.getDeviceName(), token);
        if(!baseResponse.isSuccess()){
            log.error("uploadLog validateDeviceName error, gwName:{}", edgeLogRequest.getDeviceName());
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.uploadLog(edgeLogRequest, token));
    }

    @GetMapping("/edgeLog")
    public BaseResponse edgeLog(HttpServletRequest request, @RequestParam String deviceName){
        log.info("edgeLog ===> gwName:{}", deviceName);
        String token = request.getHeader("token");
        BaseResponse baseResponse = validateDeviceName(deviceName, token);
        if(!baseResponse.isSuccess()){
            log.error("edgeLog validateDeviceName error, gwName:{}", deviceName);
            return baseResponse;
        }
        return BaseResponse.ok(deviceService.getEdgeLog(deviceName, token));
    }

    @DeleteMapping("/delete")
    public BaseResponse delete(HttpServletRequest request, @RequestParam  String deviceName){
        log.info("delete ===> gwName:{}", deviceName);
        String token = request.getHeader("token");
        List<String> roles = JwtUtils.getRole(token);
        if (!roles.contains(Constants.TENANT_ADMIN)){
            log.error("delete , user has not permission , gwName:{}", deviceName);
            return BaseResponse.error("一般用户没有添加设备权限", ResultCode.PARAM_ERROR);
        }
        List<SaasDeviceInfo> devices = deviceService.getByDeviceName(deviceName);
        if(CollectionUtils.isEmpty(devices)){
            log.error("delete getByDeviceName error, gwName:{}", deviceName);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }

        return BaseResponse.ok(deviceService.deleteCt(deviceName, token));
    }

    @PostMapping("/writeCtDevProperty")
    @ResponseBody
    public BaseResponse writeCtDevProperty(HttpServletRequest request, @RequestBody WriteDevPropertyRequest writeDevPropertyRequest) {
        log.info("writeCtDevProperty ===> writeDevPropertyRequest:{}", writeDevPropertyRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("writeCtDevProperty tenantId is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getDeviceName())){
            log.error("writeCtDevProperty gwName is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getProperty())){
            log.error("writeCtDevProperty property is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("property参数为空", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getValue())){
            log.error("writeCtDevProperty value is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("value", ResultCode.PARAM_ERROR);
        }
        String tenantToken = getCustomerDevTenantToken(token, writeDevPropertyRequest.getDeviceName());
        if(tenantToken==null){
            log.error("writeCtDevProperty tenantToken is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(writeDevPropertyRequest.getDeviceName(), tenantToken);
        if(deviceBasicData==null){
            log.error("writeCtDevProperty deviceBasicData is null, writeDevPropertyRequest:{}", writeDevPropertyRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(writeDevPropertyRequest.getGroupId())){
            writeDevPropertyRequest.setGroupId("0");
        }
        boolean result =  deviceService.writeCtDevProperty(deviceBasicData, token, writeDevPropertyRequest);
        if(!result){
            log.error("writeCtDevProperty error, writeDevProperty:{}", writeDevPropertyRequest);
        }
        return BaseResponse.ok(result);
    }

    @PostMapping("/invokeCmd")
    @ResponseBody
    public BaseResponse invokeCmd(HttpServletRequest request, @RequestBody InvokeCmdRequest invokeCmdRequest) {
        log.info("InvokeCmd ===> invokeCmdRequest:{}", invokeCmdRequest);
        String token = request.getHeader("token");
        String tenantId = JwtUtils.getTenantId(token);
        if(StringUtils.isBlank(tenantId)){
            log.error("InvokeCmd tenantId is null, invokeCmdRequest:{}", invokeCmdRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }
        if(StringUtils.isBlank(invokeCmdRequest.getDeviceName())){
            log.error("InvokeCmd gwName is null, invokeCmdRequest:{}", invokeCmdRequest);
            return BaseResponse.error("deviceName参数为空", ResultCode.PARAM_ERROR);
        }
        if(invokeCmdRequest.getPayload()==null){
            log.error("InvokeCmd payload is null, invokeCmdRequest:{}", invokeCmdRequest);
            return BaseResponse.error("payload参数为空", ResultCode.PARAM_ERROR);
        }

        String tenantToken = getCustomerDevTenantToken(token, invokeCmdRequest.getDeviceName());
        if(tenantToken==null){
            log.error("InvokeCmd tenantToken is null, invokeCmdRequest:{}", invokeCmdRequest);
            return BaseResponse.error("token异常", ResultCode.PARAM_ERROR);
        }

        DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(invokeCmdRequest.getDeviceName(), tenantToken);
        if(deviceBasicData==null){
            log.error("InvokeCmd deviceBasicData is null, invokeCmdRequest:{}", invokeCmdRequest);
            return BaseResponse.error("设备不存在", ResultCode.PARAM_ERROR);
        }
        boolean result =  deviceService.invokeCtDevice(deviceBasicData, token, invokeCmdRequest);
        if(!result){
            log.error("InvokeCmd error, invokeCmdRequest:{}", invokeCmdRequest);
        }
        return BaseResponse.ok(result);
    }
}
